
#include "bits/stdc++.h"
#include "lineType.hpp"

namespace rc{

// 对数据采样类
class sample_data
{
private:

    typedef Eigen::Matrix<float, 3, 1> M31;

    size_t mMaxSampleGroupNum;
    size_t mOneSampleMN;
    size_t mDataSetSize;
    std::vector<int> mIds;
public:
    sample_data(size_t maxSampleGroupNum, size_t oneSampleMN, size_t dataSetSize){
        mMaxSampleGroupNum = maxSampleGroupNum;
        mOneSampleMN = oneSampleMN;
        mDataSetSize = dataSetSize;
        // 构造抽样数据集合
        mIds.resize(mDataSetSize);
        for(int i = 0; i < mDataSetSize; i++) mIds[i] = i; 
    }
    ~sample_data(){}
    // 对括号进行重载    最大采样数据   一次采样的数量   如果需要测评需要输入 模型+配置参数
    void operator()(std::vector<std::vector<int>> & outSampleId, modelType* mode = nullptr, bool isFind = false){
        outSampleId.clear();

        std::random_device rd; 
        std::mt19937 gen(rd()); 
        

        for(size_t gi = 0; gi < mMaxSampleGroupNum; ++gi){
            std::vector<int> nowIds = mIds;
            std::vector<int> oneSample(mOneSampleMN);
            for(size_t si = 0; si < mOneSampleMN; ++si){// 持续抽样
                std::uniform_int_distribution<int> distrib(0, mDataSetSize - si -1);
                int id = distrib(gen);
                oneSample[si] = id;
                nowIds[id] = nowIds.back();
                nowIds.resize(nowIds.size()-1);
            }   
            outSampleId.push_back(oneSample);    
        }

        // TODO: 测评模型
    }

    // 求解模型评判模型取得分最好的 输入模型  一次采样的id  总的数据库模型
    void solveAndEvaluation(modelType* mode, std::vector<int> _ids, std::vector<M31> outXs, std::vector<M31> outYs){
        // 求解模型
        std::vector<std::vector<double>> inX(_ids.size());
        std::vector<std::vector<double>> inY(_ids.size());

        for(size_t i = 0; i < _ids.size(); ++i){
            int id = _ids[i];
            for(int j = 0; j < 3; j++){
                inX[i].push_back(outXs[id](j, 0));
                inY[i].push_back(outYs[id](j, 0));
            }
        }
        // debug 
        // std::cout << " in X = " << std::endl;
        // for(int i = 0; i < inX.size(); ++i){
        //     for(int j = 0; j < inX[i].size(); ++j){
        //         std::cout << inX[i][j] << " ";
        //     }
        //     std::cout << std::endl;
        // }
        // std::cout << std::endl;

        mode->solve(inX, inY);
        // mode->evaluate();


    }

};






}


